package com.luo.d3s.ext.aop.log.aspect;

import com.luo.d3s.ext.aop.config.D3sAopConsts;
import com.luo.d3s.ext.aop.config.D3sAopProps;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.StringJoiner;

/**
 * Web日志AOP增强切面
 *
 * @author luohq
 * @date 2023-01-29 09:57
 */
@Aspect
public class D3sWebLogAspect extends D3sBaseLogAspect {

    private Logger log = LoggerFactory.getLogger(D3sWebLogAspect.class);

    private D3sAopProps d3sAopProps;

    public D3sWebLogAspect(D3sAopProps d3sAopProps) {
        this.d3sAopProps = d3sAopProps;
    }

    @PostConstruct
    void postConstruct() {
        log.info("D3s AOP EXT - WEB LOG - Started - Pointcut: {}, configProps: {}", D3sAopConsts.WEB_MVC_POINT, this.d3sAopProps.getLog());
    }


    @Around(D3sAopConsts.WEB_MVC_POINT)
    public Object proceedWebWithLog(ProceedingJoinPoint point) throws Throwable {
        return this.proceedWithLog(point, this.d3sAopProps.getLog());
    }

    @Override
    protected String convertMethodName(Method method, Class methodClass, D3sAopProps.LogProps logProps) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String methodUrl = new StringBuilder(request.getMethod())
                .append(" ")
                .append(request.getRequestURI().toString())
                .toString();
        if (!logProps.getShowClassName()) {
            return methodUrl;
        }
        return new StringJoiner(".")
                .add(methodClass.getSimpleName())
                .add(methodUrl)
                .toString();
    }

    @Override
    protected Boolean matchPrintLog(Class methodClass, D3sAopProps.LogProps logProps) {
        return logProps.getEnableWebLog();
    }
}